<template lang="pug">
.container
  n-form.login-box(ref="formRef" :model="formData" :rules="rules")
    .logo-box
      span Italent
    n-form-item(path="userName")
      n-input(v-model:value="formData.userName" size="large" placeholder="用户名" round clearable)
    n-form-item(path="password")
      n-input(v-model:value="formData.password" size="large" type="password" placeholder="密码" round clearable)
    .verification-code
      n-form-item(path="code")
        n-input(v-model:value="formData.code" size="large" :maxlength="4" placeholder="验证码" round clearable)
      img(:src="codeImgSrc" @click="ev_getCode")
    .user-operation
      n-button(type="info" text) 忘记密码？
      n-button(type="info" text) 注册
    .login-btn(@click="ev_login")
      n-icon.icon(v-if="isLoading" :component="ArrowClockwise28Regular" size="25" color="#fff")
      span(v-else) 登录

</template>

<script setup lang="ts">
import {GetJsonWithFile} from "@/utils/tools";
import {ref, reactive, onMounted, onBeforeUnmount} from "vue"
import type {FormInst, FormRules } from 'naive-ui'
import {ArrowClockwise28Regular} from '@vicons/fluent'
import {useRouter} from "vue-router";
import {useRoutes, useUserInfo} from "@/stores";
import {getCode, getUserInfo, login} from "@/api/user";

// 路由
const router = useRouter()
// 表单ref
const formRef = ref<FormInst | null>(null)
let isLoading = ref(false)
// 图片验证码
let codeImgSrc = ref<string>('')
// 动态路由仓库实例
const routesConfig = useRoutes()
// 用户信息仓库实例
const userStore = useUserInfo()
// 触发方式
const trigger = ['input', 'blur']
// 表单校验
const rules: FormRules = {
  userName: [{required: true, message: "请填写用户名", trigger}],
  password: [
    {required: true, message: "请填写密码", trigger},
    {min: 6, message: "密码不得小于6位", trigger},
    {max: 20, message: "密码不得大于20位", trigger}
  ],
  code: [
    {required: true, message: "请填写验证码", trigger},
    {min: 4, message: "密码不得小于4位"},
  ]
}

// 用户类型
type User = {
  userName: string | null,
  password: string | null,
  code: string | null,
  key: string | null
}

const formData = reactive<User>({
  userName: 'admin',
  password: '123456',
  code: '',
  key: ''
})

// 登录
const ev_login = (e: MouseEvent) => {
  // 阻止默认行为
  e.preventDefault()
  if (isLoading.value) return
  // 校验
  formRef.value?.validate(async (err) => {
    if (err) return
    // // 获取本地路由
    // getJsonWithFile('/src/resources/menu.json').then((res: any) => {
    //   window.$message.success('登录成功')
    //   // 是否有路由
    //   if (routesConfig.routes.length < 1) {
    //     routesConfig.routes = res.data
    //     routesConfig._addRoutes(res.data, router)
    //   }
    //   // 跳转首页
    //   router.push({
    //     name: 'root'
    //   })
    // })

    isLoading.value = true

    try {
      // 登录接口
      const loginRes = await login(formData)
      // 存储token
      userStore.token = loginRes.data.accessToken || loginRes.data

      // 获取用户基本信息
      const userData = (await getUserInfo({})).data
      window.$message.success('登录成功')

      const menuList = routesConfig._menuFormat(userData.oldMenuList)

      routesConfig._addRoutes(menuList, router)

      routesConfig.routes = menuList

      userStore.userInfo = {
        companyCode: userData.companyCode,    // 账号公司 code
        roleName: userData.ename,             // 角色名称
        account: userData.pernr,              // 账号
        baseInfo: userData.pernrBaseInfo,     // 用户基本信息
        roleList: userData.roleList,          // 角色列表
        homeModuleList: userData.roleModelVos,// 首页模块权限列表
        systemList: userData.systemList,      // 系统列表
        systemModules: userData.systemModules,// 系统模块列表
        menuList: menuList
      }

      // 跳转首页
      await router.push({name: 'root'})
      isLoading.value = false
    } catch (err) {
      isLoading.value = false
      await getCode()
    }
  })
}

// 获取验证码
const ev_getCode = () => {
  getCode().then(({data}) => {
    const {code, key} = data
    codeImgSrc.value = code
    formData.key = key
  });
}

const keyDown = (e: any) => {
  if (e.key === 'Enter') {
    ev_login(e)
  }
}

onMounted(() => {
  ev_getCode()
  document.addEventListener('keydown', keyDown)
})

// 页面销毁之前
onBeforeUnmount(() => {
  document.removeEventListener('keydown', keyDown)
})

</script>

<style lang="scss" scoped>

.container {
  width: 100%;
  height: 100%;
  background: url("@/assets/images/login-bg.jpg") no-repeat fixed;
  background-size: cover;
  position: relative;
  display: flex;
  align-items: center;

  :deep(.n-form-item) {
    display: initial;
  }

  .login-box {
    padding: 1.5rem;
    background: #00000050;
    backdrop-filter: blur(30px);
    border-radius: 20px;
    width: 400px;
    position: absolute;
    right: 10%;
    display: flex;
    flex-direction: column;

    .logo-box {
      font-size: 40px;
      font-weight: 600;
    }

    .verification-code {
      display: flex;
      justify-content: space-between;

      .n-form-item {
        flex: 1;
      }

      & > img {
        width: 80px;
        height: 32px;
        cursor: pointer;
        margin-left: 20px;
        border-radius: 10px;
        margin-top: 5px;
      }
    }

    .user-operation {
      display: flex;
      align-items: center;
      justify-content: space-between;
    }

    .login-btn {
      margin-top: 1rem;
      height: 40px;
      border-radius: 20px;
      background: #ffffff99;
      backdrop-filter: blur(30px);
      cursor: pointer;
      display: flex;
      align-items: center;
      justify-content: center;
      font-size: 18px;

      &:hover {
        background: linear-gradient(-45deg, #ee7752, #e73c7e, #23a6d5, #23d5ab);
        background-size: 600% 600%;
        animation: gradientBG 5s ease infinite;

        span {
          filter: invert(100%);
        }
      }

      .icon {
        animation: spin 1s infinite linear;
      }
    }
  }
}

@keyframes gradientBG {
  0% {
    background-position: 0 50%;
  }
  50% {
    background-position: 100% 50%;
  }
  100% {
    background-position: 0 50%;
  }
}

@keyframes spin {
  0% { transform: rotate(0deg); } /* 初始状态，角度为0度 */
  100% { transform: rotate(360deg); } /* 结束状态，角度为360度（完全旋转一周）*/
}

</style>